'use strict';

// const { app } = require('egg-mock/bootstrap');

const Controller = require('egg').Controller;

class AdminController extends Controller {
  async login() {
    let { msg, msgType } = this.ctx.query;
    const users = await this.ctx.service.system.accounts.index();

    // 初始化系统
    if(users.count === 0) {
      msg = await this.sysInit();
      msgType = 'tip'
    }

    await this.ctx.render('/system/login.tpl', {
      msg, msgType,
    });


  }

  async createPageRouter(systemResourceId, pageIndex, json) {
    const { ctx } = this;

    const data = { 
      page: true, index: true, create: true, show: true, update: true, destory: true,
      title: json.title, description: json.description, path: json.path,
      controller_name: json.controller_name, status: "1"
    };

    // 批量创建路由
    let systemRouterIds = {};
    if (data.page) {
      const newData = { ... data }; // 拷贝JSON数据
      newData.title = newData.title;
      newData.description = newData.description + '_页面';
      newData.path = newData.path + '_page';
      newData.action_name = 'get';
      newData.controller_name = newData.controller_name + '.page';
      const res = await ctx.service.system.routers.new(newData);
      systemRouterIds.page = res.dataValues.id;
    }
    if (data.index) {
      const newData = { ... data }; // 拷贝JSON数据
      newData.title = newData.title + '_列表';
      newData.description = newData.description + '_列表';
      //  newData.path = newData.path;
      newData.action_name = 'get';
      newData.controller_name = newData.controller_name + '.index';
      const res = await ctx.service.system.routers.new(newData);
      systemRouterIds.index = res.dataValues.id;
    }
    if (data.create) {
      const newData = { ... data }; // 拷贝JSON数据
      newData.title = newData.title + '_新增';
      newData.description = newData.description + '_新增';
      //  newData.path = newData.path;
      newData.action_name = 'post';
      newData.controller_name = newData.controller_name + '.create';
      const res = await ctx.service.system.routers.new(newData);
      systemRouterIds.create = res.dataValues.id;
    }
    if (data.show) {
      const newData = { ... data }; // 拷贝JSON数据
      newData.title = newData.title + '_获取单条';
      newData.description = newData.description + '_获取单条';
      newData.path = newData.path + '/:id';
      newData.action_name = 'get';
      newData.controller_name = newData.controller_name + '.show';
      const res = await ctx.service.system.routers.new(newData);
      systemRouterIds.show = res.dataValues.id;
    }
    if (data.update) {
      const newData = { ... data }; // 拷贝JSON数据
      newData.title = newData.title + '_修改';
      newData.description = newData.description + '_修改';
      newData.path = newData.path + '/:id';
      newData.action_name = 'put';
      newData.controller_name = newData.controller_name + '.update';
      const res = await ctx.service.system.routers.new(newData);
      systemRouterIds.update = res.dataValues.id;
    }
    if (data.destory) {
      const newData = { ... data }; // 拷贝JSON数据
      newData.title = newData.title + '_删除';
      newData.description = newData.description + '_删除';
      newData.path = newData.path + '/:id';
      newData.action_name = 'del';
      newData.controller_name = newData.controller_name + '.destroy';
      const res = await ctx.service.system.routers.new(newData);
      systemRouterIds.destory = res.dataValues.id;
    }

    let sortIndex = 0;
    let resource_array = [];
    const resType = {
      page: 'page', index: 'api', create: 'button', show: 'api', update: 'api', destory: 'button',
    }
  
    for(let key in systemRouterIds) {
      // 根据路由，创建资源，并创建权限访问表
      sortIndex ++;
      const res = await ctx.service.system.resources.new({
        pid: systemResourceId,
        type: resType[key],
        icon: resType[key] === 'page' ? json.icon : '',
        router_id: systemRouterIds[key],
        sort: pageIndex * 10 + sortIndex,
        status: '1',
      });
      const resId = res.dataValues.id;
      resource_array.push(resId);
    }
  
    return resource_array;
  }

  async userLogin() {
    const { ctx, app, config } = this;
    const { captcha, rememberMe } = ctx.request.body;

    if (captcha !== ctx.session.login_code) {
      ctx.redirect('/login?msg=验证码不正确或已过期！&msgType=error');
    } else {
      const user = await ctx.service.system.admin.userlogin(ctx.request.body);

      if (user) {
        const resources = user['roleresource.resourceArray'] ? user['roleresource.resourceArray'].split(',') : [];
        if(resources.length === 0) {
          ctx.redirect('/login?msg=账号未分配权限，无法登陆！&msgType=error');
          return;
        }
        resources.push(0); //菜单项 router_id 为0
        const realResources = await ctx.service.system.resources.index({
          router_id: Array.isArray(resources) ? resources : [], // in 查询.
        });

        const urls =  [ { url: '/index', type: 'menu', action: 'get' }, {url: '/main', type: 'page', action: 'get' } ]; // 默认的后台首页
        realResources.rows.forEach(resource => {
          urls.push({ 
            url: resource['router.path'], action: resource['router.action'], type: resource.type,
            description: resource['router.title'], 
           });
        });

        const passport_type = config.auth.passport.type;

        // 权限表写入到session表中.
        const result = await ctx.model.Session.findOrCreate({
          where: { user_id: user.id },
          defaults: { user_id: user.id, urls, isAdmin: user['role.isAdmin'] },
        });

        // 如果记录已存在，则更新urls值
        if (!result[1]) await ctx.model.Session.update({ urls, isAdmin: user['role.isAdmin'] }, { where: { user_id: user.id } });

        if (passport_type === 'session') {

          ctx.session.userName = user.name;
          ctx.session.userId = user.id;
          ctx.session.loginTime = Date.now();
          ctx.session.maxAge = rememberMe ? 24 * 3600 * 1000 * 3 : 4 * 3600 * 1000 // 3天 || 4h          
        } else if (passport_type === 'jwt') {
          // 签发token
          const token = app.jwt.sign({
            userName: user.name,
            userId: user.id,
            loginTime: Date.now(),
          },
          config.jwt.secret, {
            expiresIn: rememberMe ? 24 * 3600 * 1000 * 3 : 4 * 3600 * 1000,
          });

          ctx.cookies.set('authorization', token, { httpOnly: false }); // 需允许token能被JS访问
        }

        // 调用 rotateCsrfSecret 刷新用户的 CSRF token
        ctx.rotateCsrfSecret();

        ctx.redirect('/index');
      } else {
        ctx.redirect('/login?msg=账号或密码不正确&msgType=error');
      }
    }
  }

  async userLogout() {
    const { ctx, config } = this;

    const userId = ctx.helper.getUserId();

    ctx.session.name = null;
    ctx.session.userId = null;
    ctx.session.loginTime = null;

    await ctx.model.Session.destroy({ where: { 'user_id': userId } });

    ctx.cookies.set('authorization', '');
    ctx.redirect('/login?msg=你已退出登陆&msgType=tip');
  }

  async register() {
    const { ctx, app } = this;
    const { msg, msgType } = ctx.query;

    // 检查是否需要初始化系统
    const users = await ctx.service.system.accounts.index();

    if(users.count === 0) {
      await this.sysInit();
    } else 
      ctx.redirect('/login?msg=请不要重复初始化&msgType=tip');
    //  await ctx.render('/system/reg.tpl', {msg, msgType});
  }

  async userRegister() {
    const { ctx, app, config } = this;
    const body = ctx.request.body;

    if (body.captcha !== ctx.session.login_code) {
      ctx.redirect('/register?msg=验证码不正确或已过期！&msgType=error');
    } else if(body.password !== body.password2 ) {
      ctx.redirect('/register?msg=两次密码不一致！&msgType=error');
    } else if(!body.account || !body.username || !body.password) {
      ctx.redirect('/register?msg=用户名、账号或密码为空！&msgType=error');
    } else if(body.account.length<4 || body.account.length>10) {
      ctx.redirect('/register?msg=账号长度应为4~10位！&msgType=error');
    } else if(body.username.length<2 || body.username.length>6) {
      ctx.redirect('/register?msg=姓名长度应为2~6位！&msgType=error');
    } else if(body.password.length<6 || body.account.length>15) {
      ctx.redirect('/register?msg=密码长度应为6~15位！&msgType=error');
    } else {
      let data = {
        account: body.account,
        role_id: body.role_id || 0,
        password: ctx.helper.md5(body.password),
        name: body.username,
        email: body.role_id,
        status: '1',
      }

      const result = await ctx.service.system.accounts.new(data);

      if (result) {
        ctx.redirect('/login?msg=注册成功请登陆！');
      } else {
        ctx.redirect('/register?msg=账号或密码不正确&msgType=error');
      }
    }
  }

  async init() {
    const { ctx, app } = this;
    const { msg, msgType } = ctx.query;

    // 检查是否需要初始化系统
    const users = await ctx.service.system.accounts.index();

    if(users.count === 0) {
      const msg = await this.sysInit();
      ctx.redirect(`/login?msg=${msg}&msgType=tip`);
    } else 
      ctx.redirect('/login?msg=请不要重复初始化&msgType=tip');
  }

  async sysInit() {
    // 系统初始化，用来创建默认系统管理员权限组，默认管理员，默认首页的访问资源
    const { ctx, app, config } = this;

    // 先清空四个表
    await ctx.model.Role.destroy({ where: { }, truncate: true });
    await ctx.model.User.destroy({ where: { }, truncate: true });
    await ctx.model.Resource.destroy({ where: { }, truncate: true });
    await ctx.model.Roleresource.destroy({ where: { }, truncate: true });
    await ctx.model.Router.destroy({ where: { }, truncate: true });

    // 创建系统管理资源
    const systemResource = await ctx.service.system.resources.new({
      pid: 0,
      router_name: '系统管理',
      controller_name: '',
      type: 'menu',
      url: '',
      icon: 'mdi mdi-account-multiple',
      router_id: 0,
      sort: 1,
      description: '系统管理',
      status: '1',
    });
    const systemResourceId = systemResource.dataValues.id;

    let resource_array = [];
    let temp_arry = [];
    let pageIndex = 1; // 页面排序索引
    temp_arry = await this.createPageRouter(systemResourceId, pageIndex, {title: '路由管理', description: '路由管理', icon: 'mdi mdi-routes', path: '/system/routers',controller_name: 'system.routers'});
    resource_array = resource_array.concat(temp_arry);

    pageIndex ++;
    temp_arry = await this.createPageRouter(systemResourceId, pageIndex, {title: '资源配置', description: '资源配置', icon: 'mdi mdi-package', path: '/system/resources',controller_name: 'system.resources'});
    resource_array = resource_array.concat(temp_arry);

    pageIndex ++;
    temp_arry = await this.createPageRouter(systemResourceId, pageIndex, {title: '资源权限配置', description: '资源权限配置', icon: 'mdi mdi-book-open-page-variant', path: '/system/roleresources',controller_name: 'system.roleresources'});
    resource_array = resource_array.concat(temp_arry);

    pageIndex ++;
    temp_arry = await this.createPageRouter(systemResourceId, pageIndex, {title: '角色管理', description: '角色管理', icon: 'mdi mdi-account-multiple-plus', path: '/system/roles',controller_name: 'system.roles'});
    resource_array = resource_array.concat(temp_arry);

    pageIndex ++;
    temp_arry = await this.createPageRouter(systemResourceId, pageIndex, {title: '账号管理', description: '账号管理', icon: 'mdi mdi-account-circle', path: '/system/accounts',controller_name: 'system.accounts'});
    resource_array = resource_array.concat(temp_arry);

    // 创建默认管理员权限组
    const mainRole = await ctx.service.system.roles.new({
      title: '系统管理员',
      description: '系统内置管理员组，最高权限，不允许修改.',
      isAdmin: '1',
      status: '1',
    });
    const mainRoleId = mainRole.dataValues.id;

    // 创建权限组资源分配
    await ctx.service.system.roleresources.new({
      resource_array: resource_array.join(','), // 资源ID编号数组
      role_id: mainRoleId,
    });

    // 创建默认管理员账号
    await ctx.service.system.accounts.new({
      account: 'cadcamzy',
      role_id: mainRoleId,
      password: '123456',
      name: '管理员',
      email: 'cadcamzy@hotmail.com',
      status: '1',
    });

    return '初始化成功,默认用户名: cadcamzy, 初始密码：123456，请登陆！';
  }

  async error() {
    const { ctx } = this;
    const id = ctx.params.id;

    await ctx.render(`/error_${id}.tpl`);
  }

}

module.exports = AdminController;
